using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using elibrary.Classes;
using elibrary.Models;
using elibrary.Models.Entities;
using UserOrderStatus = elibrary.Models.Entities.UserOrder.UserOrderStatus;

namespace elibrary.Models.Managers
{
	public class UserOrderManager
	{
		private DataContext ctx;
		private DbSet<UserOrder> orders;

		public UserOrderManager(DataContext ctx)
		{
			this.ctx = ctx;
			this.orders = ctx.orders;
		}

		public void add(UserOrder order,bool autoSave=true)
		{
			orders.Add(order);
			if (autoSave)
				ctx.SaveChanges();
		}

		public UserOrder get(int id)
		{
			return orders.SingleOrDefault(q => q.id == id);
		}

		public List<UserOrder> getAllByUser(int uid)
		{
			var r = orders.Where(q => q.buyerId == uid);

			return r != null && r.Any() ? r.ToList() : new List<UserOrder>();
		}

		public List<UserOrder> getAllByStatus(UserOrderStatus status)
		{
			var r = orders.Where(q => q.status == status);

			return r != null && r.Any() ? r.ToList() : new List<UserOrder>();
		}

		public List<Book> getPurchasesByUserId(int uid)
		{
			List<Book> toReturn = new List<Book>();
			List<UserOrder> purchases = Utilities.ensureRs<UserOrder>(orders.Where( q => 
				q.buyerId == uid && ((int)q.status) > 0 && ((int)q.status) < 3 ));

			foreach(var purchase in purchases)
			{
				List<UserOrderItem> ois = purchase.orderItems;

				foreach(var oi in ois)
					toReturn.Add(oi.book);
			}

			return toReturn;
		}

		public List<UserOrder> getAllAvailable()
		{
			return Utilities.ensureRs<UserOrder>(orders.Where(q => ((int)q.status) < 5));
		}

		public List<Dictionary<string,object>> getAllAvailableClient()
		{
			List<Dictionary<string,object>> toReturn = new List<Dictionary<string,object>>();
			List<UserOrder> cols = this.getAllAvailable();

			foreach (var col in cols)
				toReturn.Add(col.clientManagerObject);

			return toReturn;
		}

		public List<UserOrder> getHistoricalByUserId(int uid)
		{
			return Utilities.ensureRs<UserOrder>(orders.Where( q => q.buyerId == uid && 
				((int)q.status) > 1 && ((int)q.status) < 5 ));
		}

		public UserOrder getPendingByUserId(int uid)
		{
			return orders.SingleOrDefault(q => q.buyerId == uid 
				&& q.status == UserOrderStatus.Pending);
		}

		public List<UserOrder> getCompletedByUserId(int uid)
		{
			return Utilities.ensureRs<UserOrder>(orders.Where( q => q.buyerId == uid && 
				q.status == UserOrderStatus.Completed ));
		}

		public List<UserOrder> getCancelledByUserId(int uid)
		{
			return Utilities.ensureRs<UserOrder>(orders.Where( q => q.buyerId == uid && 
				q.status == UserOrderStatus.Cancelled ));
		}

		public List<UserOrder> getExpiredByUserId(int uid)
		{
			return Utilities.ensureRs<UserOrder>(orders.Where( q => q.buyerId == uid && 
				q.status == UserOrderStatus.Expired ));
		}

		public UserOrder getCartByUserId(int uid)
		{
			return orders.SingleOrDefault(q => q.status == UserOrderStatus.Cart
				&& q.buyerId == uid);
		}

		public void delete(int id,bool autoSave=true)
		{
			delete(get(id),autoSave);
		}

		public void delete(UserOrder order,bool autoSave=true)
		{
			if (order == null)
				return;

			orders.Remove(order);
			if (autoSave)
				ctx.SaveChanges();
		}
	}
}